import { PBRShader } from "./js/shaders.js";
const canvas = document.getElementById("renderCanvas"); // Get the canvas element
let shadowGenerator;
// 尝试获取 WebGL2 上下文
const gl = canvas.getContext("webgl2");
if (gl) {
  console.log("支持 WebGL 2.0");
} else {
  alert("设备不支持 WebGL 2.0");
}
// const vertexBuffer = new BABYLON.VertexBuffer()
const engine = new BABYLON.Engine(canvas, true, {
  antialias: true, // 开启抗锯齿
}); // Generate the BABYLON 3D engine
function showWorldAxis(size, scene) {
  const makeAxis = function (axis, color) {
    const axisMaterial = new BABYLON.StandardMaterial("axisMat", scene);
    axisMaterial.diffuseColor = color;
    axisMaterial.emissiveColor = color;

    const axisLine = BABYLON.MeshBuilder.CreateLines(
      "axis" + axis,
      {
        points: [
          BABYLON.Vector3.Zero(),
          axis === "X"
            ? new BABYLON.Vector3(size, 0, 0)
            : axis === "Y"
            ? new BABYLON.Vector3(0, size, 0)
            : new BABYLON.Vector3(0, 0, size),
        ],
      },
      scene
    );
    axisLine.color = color;
  };

  makeAxis("X", BABYLON.Color3.Red()); // 红色X轴
  makeAxis("Y", BABYLON.Color3.Green()); // 绿色Y轴
  makeAxis("Z", BABYLON.Color3.Blue()); // 蓝色Z轴
}
const createScene = function () {
  // Creates a basic Babylon Scene object
  const scene = new BABYLON.Scene(engine);
  const camera = new BABYLON.ArcRotateCamera(
    "camera",
    -Math.PI / 2,
    Math.PI / 2.5,
    3,
    new BABYLON.Vector3(0, 0, 0),
    scene
  );
  // camera.upperBetaLimit = Math.PI / 2.1;    // 限制相机上下旋转角度
  // Targets the camera to scene origin
  camera.setTarget(BABYLON.Vector3.Zero());
  // This attaches the camera to the canvas
  camera.attachControl(canvas, true);
  // const sphere = BABYLON.MeshBuilder.CreateSphere(
  //   "sphere",
  //   { diameter: 2, segments: 32 },
  //   scene
  // );
  // sphere.position.y = 30;
  showWorldAxis(5, scene);
  // 平行光
  const light = new BABYLON.DirectionalLight(
    "light",
    new BABYLON.Vector3(0, -1, -1),
    scene
  );
  light.intensity = 1.0;
  light.autoCalcShadowZBounds = true;
  // 阴影生成器
  shadowGenerator = new BABYLON.CascadedShadowGenerator(1024, light); // 创建级联阴影生成器
  shadowGenerator.numCascades = 4; // 阶梯数量
  shadowGenerator.lambda = 0.5; // 阴影分割权重
  shadowGenerator.shadowMaxZ = 150;
  shadowGenerator.shadowMinZ = 0.1;
  shadowGenerator.filteringQuality = BABYLON.ShadowGenerator.QUALITY_LOW;
  shadowGenerator.filter = BABYLON.ShadowGenerator.FILTER_PCF; // PCF软阴影
  // 地面
  const floor = BABYLON.MeshBuilder.CreateGround("ground", {
    width: 100,
    height: 100,
  });
  //   floor.position.y = 0.1;
  floor.checkCollisions = true;
  floor.receiveShadows = true;
  return scene;
};

// 加载模型
const loadModel = async function (scene) {
  let model1 = await BABYLON.ImportMeshAsync(
    "./models/scene.gltf",
    // "./models/wrench.gltf",
    // "./models/BoomBox.glb",
    // "./models/model.glb",
    scene
  ).then((result) => {
    // console.log(result);
    console.log(result);
    console.warn("合并失败，MergeMeshes 返回 null");
    let mesh = scene.getMeshByName("Frying_Pan_M_Pan_0"); // scene.getMeshByName("_wrench_hi_Volume18");
    shadowGenerator.addShadowCaster(mesh); // 投射阴影
    if (mesh) {
      const hasTangents = mesh.isVerticesDataPresent(
        BABYLON.VertexBuffer.TangentKind
      );
      // console.log('tangent:', mesh.getVerticesData(BABYLON.VertexBuffer.TangentKind));
      console.log("是否包含切线:", hasTangents);
    }
    mesh.position = new BABYLON.Vector3(0, 100, 0);
    mesh.scaling = new BABYLON.Vector3(50, 50, 50);
    let pbrmat = mesh.material;
    console.log("pbrmat", pbrmat);
    const customMaterial = PBRShader(scene, "customPBR");
    // 传递 贴图
    customMaterial.setTexture("albedoTexture", pbrmat.albedoTexture); // 基本颜色
    customMaterial.setTexture("normalTexture", pbrmat.bumpTexture); // 法线贴图
    customMaterial.setTexture(
      "metallicRoughnessTexture",
      pbrmat.metallicTexture
    ); // 金属度和粗糙度贴图
    mesh.material = customMaterial;
    return mesh;
  });
  // startMove(scene, model1);
  // startAnimation(model1);
};
const scene = await createScene(); //Call the createScene function
loadModel(scene);
// Register a render loop to repeatedly render the scene
engine.runRenderLoop(function () {
  scene.render();
});
// Watch for browser/canvas resize events
window.addEventListener("resize", function () {
  engine.resize();
});
